package com.linkallcloud.deapi;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.annotation.JSONField;
import org.apache.commons.beanutils.BeanUtils;

import com.linkallcloud.deapi.tuils.Encrypts;

public class DeRequest implements Serializable {
    private static final long serialVersionUID = 2940387898003364148L;

    private String id;// 消息ID（发送方提供）
    private String tid;// 消息ID（de生成）
    private String content;// 消息内容
    private String target;// 接收消息的接口ename
    private String receiver;// 接收应用的key
    private String sender;// 发送应用的key
    private Long dt;// 消息发送时间
    private String sign;// 消息签名，MD5( requestKey + id + content + target + receiver + sender + dt )

    private String encrypt;// content是否需要加密

    /**
     * 区域权限 [ { id: 916, code: '33', name: '浙江' } ]
     */
    private String permAreas;
    /**
     * 机构权限 [ { id: 2, code: '33', name: '浙江' } ]
     */
    private String permOrgs;

    private String remark;// 保留字段：备注

    public DeRequest() {
        super();
    }

    public DeRequest(String id, String content, String target, String receiver, String sender) {
        this();
        this.id = id;
        this.content = content;
        this.target = target;
        this.receiver = receiver;
        this.sender = sender;
        this.dt = System.currentTimeMillis();
    }

    public static DeRequest example() {
        return new DeRequest(UUID.randomUUID().toString().replace("-", ""), "example_request_content",
                "receiver_app_face_ename", "receiver_app_key", "sender_app_key");
    }

    public DeRequest clone() {
        DeRequest dr = null;
        try {
            dr = this.getClass().getDeclaredConstructor().newInstance();
            BeanUtils.copyProperties(dr, this);
        } catch (Throwable e) {
            // log.warn("Fail to copy properties!", e);
        }
        return dr;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTid() {
        return tid;
    }

    public void setTid(String tid) {
        this.tid = tid;
    }

    public String generateId() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getTarget() {
        return target;
    }

    public void setTarget(String target) {
        this.target = target;
    }

    public String getReceiver() {
        return receiver;
    }

    public void setReceiver(String receiver) {
        this.receiver = receiver;
    }

    public String getSender() {
        return sender;
    }

    public void setSender(String sender) {
        this.sender = sender;
    }

    public Long getDt() {
        return dt;
    }

    public void setDt(Long dt) {
        this.dt = dt;
    }

    public String getEncrypt() {
        return encrypt;
    }

    public void setEncrypt(String encrypt) {
        this.encrypt = encrypt;
    }

    public List<Oid> permAreas() {
        return (permAreas == null || permAreas.length() <= 0) ? null : JSON.parseArray(permAreas, Oid.class);
    }

    public String getPermAreas() {
        return permAreas;
    }

    public void setPermAreas(String permAreas) {
        this.permAreas = permAreas;
    }

    public List<Oid> permOrgs() {
        return (permOrgs == null || permOrgs.length() <= 0) ? null : JSON.parseArray(permOrgs, Oid.class);
    }

    public String getPermOrgs() {
        return permOrgs;
    }

    public void setPermOrgs(String permOrgs) {
        this.permOrgs = permOrgs;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    public void sign(String signKey) throws DeApiException {
        if (this.dt == null || this.dt.longValue() <= 0) {
            this.dt = new Date().getTime();
        }
        this.sign = Encrypts.md5(signKey + id + content + target + receiver + sender + dt);
    }

    public void verify(String signKey) throws DeApiException {
        if (target == null || target.length() == 0) {
            throw new DeApiException("error_target", "target参数错误");
        }
        if (receiver == null || receiver.length() == 0) {
            throw new DeApiException("error_receiver", "receiver参数错误");
        }
        if (sender == null || sender.length() == 0) {
            throw new DeApiException("error_sender", "sender参数错误");
        }
        if (dt == null || dt.longValue() <= 0) {
            throw new DeApiException("error_dt", "dt参数错误");
        }
        if (isTimeout()) {
            throw new DeApiException("error_timeout", "超时错误");
        }
        String mySign = Encrypts.md5(signKey + id + content + target + receiver + sender + dt);
        if (mySign == null || !(mySign.equals(this.getSign()))) {
            throw new DeApiException("error_sign", "签名验证错误");
        }
    }

    @JSONField(serialize = false)
    public boolean isTimeout() {
        return new Date().getTime() - this.getDt() > 30000;// 默认超时时间：30秒
    }

}
